
// 原型链（普通对象，为构造函数的实例化共享属性和方法）所有实例引用的都是同一个对象
// 构造函数的实例=》普通对象
// 使用prototype可以将方法挂到原型上，内存只保留一份
// __proto__理解为指针，实例对象的属性，指向构造函数的原型（prototype）如下p1. __proto__===Person.prototype
// 一:实例(构造函数)
// 原型prototype=>函数特有为了继承
// 原型链__proto__=>[[prototype]]普通对象和函数都有的
function Person() {
  this.say = function () {
    console.log('唱歌');
  }

}
var p1 = new Person()
var p2 = new Person()
p1.say()
p2.say()

// 利用构造函数的prototype实现，调用时内存就只用一次
// Person.prototype.xyj=function(){

//   console.log('西游记');
// }
// var p1=new Person()
// var p2=new Person()
// // 解释了实例化对象为啥能调用构造函数的方法
console.log(p1.__proto__ === Person.prototype);
console.log(Object.getPrototypeOf(p1) === Person.prototype);
p1.xyj()
p1.say()
console.log(p1.toString());
p2.xyj()

// 原型链：实例(化)对象（new Person）调用属性时依次从实例(Person)本身，构造函数原型(Person.prototype)，原型的原型去寻找（即原型链的顶层，通常是Object.prototype）。
// 如果在整个原型链上都无法找到该属性，JavaScript引擎将返回undefined。
// 属性的查找顺序实例化对象=》=》找他的父级 向上直到null=》没有报错
// 寻找私有属性（属于自己的）hasOwnProperty
let item
for (item in p1) {
  if (p1.hasOwnProperty(item)) {
    console.log(item);
  }
}
